package ee.ut.math.chess.base.model.chesspiece;

import java.util.ArrayList;
import java.util.List;

import ee.ut.math.chess.base.model.Move;
import ee.ut.math.chess.base.model.Position;
import ee.ut.math.chess.base.model.SpecialMoveType;
import ee.ut.math.chess.game.model.Game;
import ee.ut.math.chess.game.model.GameLogic;

public class King extends ChessPiece {

	private static final long serialVersionUID = 1L;
	private boolean inInitialPosition = true;
	private long value = 200;

	public King(Color color) {
		this.color = color;
	}

	@Override
	public void setInInitialPosition(boolean inInitialPosition) {
		this.inInitialPosition = inInitialPosition;
	}

	@Override
	public boolean isInInitialPosition() {
		return inInitialPosition;
	}

	@Override
	public List<Move> getLegalMoves(int x, int y, Game game,
			boolean onlyKingThreatening) {
		List<Move> result = new ArrayList<Move>();
		for (int i = -1; i < 2; i++) {
			for (int j = -1; j < 2; j++) {
				if (i == 0 && j == 0) {
					continue;
				}
				if (x + i >= 0 && x + i < 8 && y + j >= 0 && y + j < 8) {
					ChessPiece chessPiece = game.getBoard().getChessPiece(
							x + i, y + j);
					if (chessPiece == null || chessPiece.getColor() != color) {
						result.add(new Move(x, y, x + i, y + j));
					}
				}
			}
		}

		if (!onlyKingThreatening && inInitialPosition) {
			if (checkCastlingRight(x, y, game)) {
				result.add(new Move(x, y, x, y + 2, SpecialMoveType.CASTLING));
			}
			if (checkCastlingLeft(x, y, game)) {
				result.add(new Move(x, y, x, y - 2, SpecialMoveType.CASTLING));
			}
		}
		return result;
	}

	public boolean checkCastlingRight(int x, int y, Game game) {
		ChessPiece chessPiece = game.getBoard().getChessPiece(x, 7);
		if (chessPiece != null && chessPiece.isInInitialPosition()) {
			for (int i = y + 1; i < 7; i++) {
				ChessPiece chessPiece2 = game.getBoard().getChessPiece(x, i);
				if (chessPiece2 != null) {
					return false;
				}
			}
			for (int i = y; i < 8; i++) {
				Position position = new Position(x, i);
				Move threateningMove = GameLogic.positionIsThreatenedBy(
						position, chessPiece.getColor().getOpposite(), game);
				if (threateningMove != null) {
					return false;
				}
			}
			return true;
		}
		return false;
	}

	public boolean checkCastlingLeft(int x, int y, Game game) {
		ChessPiece chessPiece = game.getBoard().getChessPiece(x, 0);
		if (chessPiece != null && chessPiece.isInInitialPosition()) {
			for (int i = y - 1; i > 0; i--) {
				ChessPiece chessPiece2 = game.getBoard().getChessPiece(x, i);
				if (chessPiece2 != null) {
					return false;
				}
			}
			for (int i = y; i >= 0; i--) {
				Position position = new Position(x, i);
				Move threateningMove = GameLogic.positionIsThreatenedBy(
						position, chessPiece.getColor().getOpposite(), game);
				if (threateningMove != null) {
					return false;
				}
			}
			return true;
		}
		return false;
	}
	public long getValue() {
		return value;
	}
}
